/*
 * UAE - The Un*x Amiga Emulator
 *
 * Unix file system handler for AmigaDOS
 *
 * Copyright 1997 Bernd Schmidt
 */

#pragma once

#include "autoconf.h"

#define FILEFLAG_DIR 0x1
#define FILEFLAG_ARCHIVE 0x2
#define FILEFLAG_WRITE 0x4
#define FILEFLAG_READ 0x8
#define FILEFLAG_EXECUTE 0x10
#define FILEFLAG_SCRIPT 0x20
#define FILEFLAG_PURE 0x40

struct hardfilehandle;

struct hardfiledata
{
    ulong64 virtsize; // virtual size
    ulong64 physsize; // physical size (dynamic disk)
    ulong64 offset;
    int nrcyls;
    int secspertrack;
    int surfaces;
    int reservedblocks;
    int blocksize;
    struct hardfilehandle* handle;
    int handle_valid;
    int readonly;
    int dangerous;
    int flags;
    byte* cache;
    int cache_valid;
    ulong64 cache_offset;
    TCHAR vendor_id[8 + 1];
    TCHAR product_id[16 + 1];
    TCHAR product_rev[4 + 1];
    TCHAR device_name[256];
    /* geometry from possible RDSK block */
    int cylinders;
    int sectors;
    int heads;
    byte* virtual_rdb;
    ulong64 virtual_size;
    int unitnum;
    int byteswap;
    int adide;

    byte* vhd_header;
    uint vhd_bamoffset;
    uint vhd_bamsize;
    uint vhd_blocksize;
    uint vhd_type;
    byte* vhd_sectormap;
    ulong64 vhd_sectormapblock;
    uint vhd_bitmapsize;
    ulong64 vhd_footerblock;

    int drive_empty;
    TCHAR* emptyname;
};

#define HFD_FLAGS_REALDRIVE 1

struct hd_hardfiledata
{
    struct hardfiledata hfd;
    int bootpri;
    ulong64 size;
    int cyls;
    int heads;
    int secspertrack;
    int cyls_def;
    int secspertrack_def;
    int heads_def;
    TCHAR* path;
    int ansi_version;
};

#define HD_CONTROLLER_UAE 0
#define HD_CONTROLLER_IDE0 1
#define HD_CONTROLLER_IDE1 2
#define HD_CONTROLLER_IDE2 3
#define HD_CONTROLLER_IDE3 4
#define HD_CONTROLLER_SCSI0 5
#define HD_CONTROLLER_SCSI1 6
#define HD_CONTROLLER_SCSI2 7
#define HD_CONTROLLER_SCSI3 8
#define HD_CONTROLLER_SCSI4 9
#define HD_CONTROLLER_SCSI5 10
#define HD_CONTROLLER_SCSI6 11
#define HD_CONTROLLER_PCMCIA_SRAM 12
#define HD_CONTROLLER_PCMCIA_IDE 13

#define FILESYS_VIRTUAL 0
#define FILESYS_HARDFILE 1
#define FILESYS_HARDFILE_RDB 2
#define FILESYS_HARDDRIVE 3

#define MAX_FILESYSTEM_UNITS 30
#define FILESYS_MAX_BLOCKSIZE 2048

struct uaedev_mount_info;
extern struct uaedev_mount_info options_mountinfo;

hardfiledata* get_hardfile_data(int nr);
int hdf_getnumharddrives();
TCHAR* hdf_getnameharddrive(int index, int flags, int* sectorsize, int* dangerousdrive);
int isspecialdrive(const TCHAR* name);
int hdf_read_rdb(struct hardfiledata* hfd, void* buffer, ulong64 offset, int len);
int get_native_path(uint lock, TCHAR* out);
int hdf_init_target();
int hdf_open_target(struct hardfiledata* hfd, const TCHAR* name);
int hdf_dup_target(struct hardfiledata* dhfd, const struct hardfiledata* shfd);
void hdf_close_target(struct hardfiledata* hfd);
int hdf_read_target(struct hardfiledata* hfd, void* buffer, ulong64 offset, int len);
int hdf_write_target(struct hardfiledata* hfd, void* buffer, ulong64 offset, int len);
int hdf_resize_target(struct hardfiledata* hfd, ulong64 newsize);
int nr_units();
int nr_directory_units(CConfiguration* conf);
int is_hardfile(int unit_no);
int get_filesys_unitconfig(CConfiguration* conf, int index, mountedinfo* mi);
void validatevolumename(CString* s);
void validatevolumename(TCHAR* s);
void validatedevicename(CString* s);
TCHAR* filesys_createvolname(const TCHAR* volname, const TCHAR* rootdir, const TCHAR* def);
int kill_filesys_unitconfig(CConfiguration* conf, int nr);
int move_filesys_unitconfig(CConfiguration* conf, int nr, int to);
int sprintf_filesys_unit(TCHAR* buffer, int num);
int filesys_eject(int nr);
void filesys_vsync();
int filesys_media_change(const TCHAR* rootdir, int inserted, DeviceConfigInfo* dci);
int hardfile_remount(int nr);
int filesys_insert(int nr, TCHAR* volume, const TCHAR* rootdir, bool readonly, int flags);
void filesys_flush_cache();
TCHAR* build_nname(const TCHAR* d, const TCHAR* n);
void filesys_start_threads();
void filesys_cleanup();
void filesys_free_handles();
void filesys_reset();
void filesys_prepare_reset();
void filesys_install();
void filesys_install_code();
byte* save_filesys_common(int* len);
byte* restore_filesys_common(byte* src);
byte* save_filesys(int num, int* len);
byte* restore_filesys(byte* src);
int save_filesys_cando();